package com.qf.fronted.dao.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.qf.fronted.dao.OrderDao;
import com.qf.fronted.domain.GoodId;
import com.qf.fronted.domain.Order;
import com.qf.utils.DataUtils;
import com.qf.utils.DbUtils;
import com.qf.utils.DruidUtils;
import jdk.nashorn.internal.ir.CallNode;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.temporal.TemporalUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class OrderDaoImpl implements OrderDao {

    QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());

    /**
     * 插入订单信息
     * @param orderNo           订单编号
     * @param price              商品购买价格
     * @param num                购买数量
     * @param orderStatus        订单的状态
     * @param appraiseStatus     评价状态
     * @param userId             订单属于那个用户
     */
    @Override
    public void insertOrder(String orderNo, BigDecimal price, Integer num, String goodsImg, String goodsTitle,
                            Integer orderStatus, Integer appraiseStatus, Integer userId, Integer goodId, Connection conn) throws SQLException {

        StringBuffer insertSql  = new StringBuffer("insert into orders(o_no, o_good_price, o_num, o_status, o_appraise_status, ")
                .append("o_user_id, o_create_time, o_good_id, o_good_img, o_good_title) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");


        PreparedStatement ps = conn.prepareStatement(insertSql.toString());
        ps.setObject(1, orderNo);
        ps.setObject(2, price);
        ps.setObject(3, num);
        ps.setObject(4, orderStatus);
        ps.setObject(5, appraiseStatus);
        ps.setObject(6, userId);
        ps.setObject(7, new Date());
        ps.setObject(8, goodId);
        ps.setObject(9, goodsImg);
        ps.setObject(10, goodsTitle);

        ps.executeUpdate();

        ps.close();
    }

    // 插入订单的收货地址
    @Override
    public void insertOrderAddress(String orderNo, Integer defaultTakeDelivertyAddressId, Connection conn) throws SQLException {
        String insertSql  = "insert into order_address(o_no, o_address) values(?, ?)";

        PreparedStatement ps = conn.prepareStatement(insertSql.toString());
        ps.setObject(1, orderNo);
        ps.setObject(2, defaultTakeDelivertyAddressId);

        ps.executeUpdate();
        ps.close();
    }

    /**
     * 查询指定订单编号的订单
     * @param orderNo
     * @return
     */
    @Override
    public List<Order> getOrdersOfOrderNo(String orderNo) {
        List<Order> list = null;
        String sql = "select o_good_price goodPrice, o_num goodNum from orders where o_no = ?";
        Connection connection = DbUtils.getConnection();

        try {
            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setObject(1, orderNo);
            ResultSet rs = ps.executeQuery();

            list = DataUtils.getAll(Order.class, rs);
            DbUtils.colse(rs, ps, connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 根据订单的状态查询对应订单
     * @param status
     * @return
     */
    @Override
    public List<Order> getOrdersByStatus(Integer status, Integer userId) {
        List<Order> list = null;
        StringBuffer sql = new StringBuffer("select o_id id, o_no orderNo, o_good_price goodPrice, o_num goodNum, o_good_img goodsImg, ")
                .append(" o_status status, o_appraise_status praiseStatus, o_create_time createTime, o_pay_time payTime, o_good_title goodsTitle ")
                .append(" from orders where o_status = ? and o_user_id = ?")
                .append(" ORDER BY o_create_time desc");

        Connection connection = DbUtils.getConnection();

        try {
            PreparedStatement ps = connection.prepareStatement(sql.toString());
            ps.setObject(1, status);
            ps.setObject(2, userId);

            ResultSet rs = ps.executeQuery();

            list = DataUtils.getAll(Order.class, rs);
            DbUtils.colse(rs, ps, connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 删除订单
     * @param orderNo
     * @throws SQLException
     */
    @Override
    public void deleteOrder(String orderNo) throws SQLException {
        String sql = "delete from orders where o_no = ?";
        queryRunner.update(sql,orderNo);
    }

    /**
     * 计算订单时间
     *
     */
    @Override
    public void CalculateOrderTime(ScheduledExecutorService service) {
        StringBuffer sql = new StringBuffer("select o_id id, o_no orderNo, o_good_price goodPrice, o_num goodNum, o_good_img goodsImg, ")
                .append(" o_status status, o_appraise_status praiseStatus, o_create_time createTime, o_pay_time payTime, o_good_title goodsTitle ")
                .append(" from orders where SECOND(TIMEDIFF(SYSDATE(),o_create_time))>30 and o_status = 0");

        try {
            List<Order> query = queryRunner.query(sql.toString(), new BeanListHandler<>(Order.class));
            if (query.size() != 0) {
                for (Order order : query) {
                    TimeOutOrderCancellation(order.getOrderNo());
                }
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    /**
     * 超时取消订单后并且将库存还回去
     * @param orderNo
     */
    @Override
    public void TimeOutOrderCancellation(String orderNo) {
        //更新订单状态
        String sql = "update orders set o_status = ? where o_no = ?";

        //联合查询得到订单中的商品的id和库存还有订单中商品数量
        String sql1 = "select goods_id goodId,stock_num goodNums,o_num orderGoodNums from goods join orders on goods_id = o_good_id where o_no = ?";

        //加回库存
        String sql2 = "update goods set stock_num = ? where goods_id = ?";
        try {
            queryRunner.update(sql,2,orderNo);
            List<GoodId> query = queryRunner.query(sql1, new BeanListHandler<>(GoodId.class), orderNo);
            for (int i = 0; i < query.size(); i++) {
                queryRunner.update(sql2,query.get(i).getGoodNums()+query.get(i).getOrderGoodNums(),query.get(i).getGoodId());
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    /**
     * 取消订单
     * @param orderNo
     * @throws SQLException
     */
    @Override
    public void cancelOrder(String orderNo) throws SQLException {
        TimeOutOrderCancellation(orderNo);
    }


    // 更新指定订单编号的订单的状态
    @Override
    public void updateOrderStatus(String orderNo, Integer newStatus,Connection connection){
        String updateStatusSql = "update orders set o_status = ?, o_pay_time = ? where o_no = ?";
        try {
            queryRunner.update(connection,updateStatusSql, newStatus, new Date(), orderNo);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }


    @Override
    public List<Order> getOrderInfo(String orderNo) {
        String sql = "select o_id id,o_user_id userId,o_good_title goodsTitle,o_good_price goodPrice,o_num goodNum,o_create_time createTime from orders where o_no=?";
        try {
            return queryRunner.query(sql, new BeanListHandler<>(Order.class), orderNo);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return new ArrayList<>(0);
    }
}
